﻿using LightCAD.Core;
using LightCAD.Core.Elements;
using LightCAD.Runtime;
using SkiaSharp;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.Metrics;
using System.Linq;
using System.Runtime;
using System.Text;
using System.Threading.Tasks;
using LightCAD.MathLib;
using netDxf.Entities;

namespace LightCAD.Drawing.Actions
{
    /// <summary>
    /// _ellipse 椭圆
    /// </summary>
    public class EllipseAction : Curve2dAction
    {
        public static LcCreateMethod[] CreateMethods;
        static EllipseAction()
        {
            CreateMethods = new LcCreateMethod[]
            {
                new LcCreateMethod
                {
                    Name = "C",
                    Description = "指定中心点创建椭圆",
                    Steps = new LcCreateStep[]
                    {
                        new LcCreateStep { Name=  "Step0", Options= "指定椭圆中心点:" },
                        new LcCreateStep { Name=  "Step1", Options= "指定轴端点:" },
                        new LcCreateStep { Name=  "Step2", Options= "指定另一个半轴长度:" },
                    }
                },
                new LcCreateMethod
                {
                    Name = "",
                    Description = "指定轴，端点创建椭圆",
                    Steps = new LcCreateStep[]
                    {
                        new LcCreateStep { Name=  "Step0", Options= "指定轴端点:" },
                        new LcCreateStep { Name=  "Step1", Options= "指定轴另一个端点:" },
                        new LcCreateStep { Name=  "Step2", Options= "指定另一个半轴长度:" },
                    }
                },
                new LcCreateMethod
                {
                    Name = "A",
                    Description = "椭圆弧",
                    Steps = new LcCreateStep[]
                    {
                        new LcCreateStep { Name=  "Step0", Options= "指定轴端点:" },
                        new LcCreateStep { Name=  "Step1", Options= "指定轴另一个端点:" },
                        new LcCreateStep { Name=  "Step2", Options= "指定另一个半轴长度:" },
                        new LcCreateStep { Name=  "Step3", Options= "指定起点角度:" },
                        new LcCreateStep { Name=  "Step4", Options= "指定端点角度:" },
                    }
                }
            };
        }

        internal static void Initilize()
        {
            ElementActions.Ellipse = new EllipseAction();
            LcDocument.ElementActions.Add(BuiltinElementType.Ellipse, ElementActions.Ellipse);
        }
        private EllipseAction() { }
        public EllipseAction(IDocumentEditor docEditor) : base(docEditor)
        {


        }
        private LcCreateMethod _currMethod = null;
        private Vector2 _p0;
        private Vector2 _p1;
        private Vector2 _p2;
        private Vector2 _p3;
        private Vector2 _p4;
        public async void ExecCreate(string[] args = null)
        {
            if (args?.Length == 0)
                args = new string[] { "" };
            PointInputer inputer = new PointInputer(this.docEditor);
            this.StartCreating();

            _currMethod = CreateMethods.ToList().Find(m => m.Name == args[0]);
            if (_currMethod == null)
                 CancelCreate();
            else if (_currMethod.Name == "C")
                createByCP();
            else if (_currMethod.Name == "")
                createByAEP();
            else if (_currMethod.Name == "A")
                createByArc();
            async void createByCP()
            {
            cp_step0:
                var cp_result0 = await inputer.Execute(_currMethod.Steps[0].Options);
                if (inputer.isCancelled || cp_result0 == null)
                    goto cancel;
                else if (cp_result0.ValueX == null)
                {
                    if (cp_result0.Option != null)
                    {
                        inputer.WriteInfo("TODO..");
                    }
                    goto cp_step0;
                }
                else
                {
                    _p0 = (Vector2)cp_result0.ValueX;     //椭圆的圆心的值
                    goto cp_step1;
                }
            cp_step1:
                var cp_result1 = await inputer.Execute(_currMethod.Steps[1].Options);
                if (inputer.isCancelled || cp_result1 == null)
                    goto cancel;
                else if (cp_result1.ValueX == null)
                {
                    if (cp_result1.Option != null)
                    {
                        inputer.WriteInfo("TODO..");
                    }
                    goto cp_step1;
                }
                else
                {
                    _p1 = (Vector2)cp_result1.ValueX;   //椭圆的第一个端点的值
                    goto cp_step2;
                }
            cp_step2:
                var cp_result2 = await inputer.Execute(_currMethod.Steps[2].Options);
                if (inputer.isCancelled || cp_result2 == null)
                    goto cancel;
                else if (cp_result2.ValueX == null)
                {
                    if (cp_result2.Option != null)
                    {
                        //if(cp_result2.Option is double)
                        //{
                        //    var a = cp_result2.Option; 
                        //}
                        inputer.WriteInfo("TODO..");
                    }
                    goto cp_step2;
                }
                else
                {
                    //if(cp_result2.Option is double)
                    //{
                        
                    //}
                    _p2 = (Vector2)cp_result2.ValueX;   //椭圆的第二个端点的值
                    Create();
                }
            cancel:
                CancelCreate();
            }
            async void createByAEP()
            {
            aep_step0:
                var aep_result0 = await inputer.Execute(_currMethod.Steps[0].Options);
                if (inputer.isCancelled || aep_result0 == null)
                    goto cancel;
                else if (aep_result0.ValueX == null)
                {
                    if (aep_result0.Option != null)
                    {
                        inputer.WriteInfo("TODO..");
                    }
                    goto aep_step0;
                }
                else
                {
                    _p0 = (Vector2)aep_result0.ValueX;
                    goto aep_step1;
                }
            aep_step1:
                var aep_result1 = await inputer.Execute(_currMethod.Steps[1].Options);
                if (inputer.isCancelled || aep_result1 == null)
                    goto cancel;
                else if (aep_result1.ValueX == null)
                    goto aep_step1;
                else
                {
                    _p1 = (Vector2)aep_result1.ValueX;
                    goto aep_step2;
                }
            aep_step2:
                var aep_result2 = await inputer.Execute(_currMethod.Steps[2].Options);
                if (inputer.isCancelled || aep_result2 == null)
                    goto cancel;
                else if (aep_result2.ValueX == null)
                    goto aep_step2;
                else
                {
                    _p2 = (Vector2)aep_result2.ValueX;
                    Create();
                }
            cancel:
                CancelCreate();
            }
            async void createByArc()
            {
            step0:
                var arc_result0 = await inputer.Execute(_currMethod.Steps[0].Options);
                if (inputer.isCancelled || arc_result0 == null)
                    goto cancel;
                else if (arc_result0.ValueX == null)
                {
                    if (arc_result0.Option != null)
                    {
                        inputer.WriteInfo("TODO..");
                    }
                    goto step0;
                }
                else
                {
                    _p0 = (Vector2)arc_result0.ValueX;
                    goto step1;
                }
            step1:
                var arc_result1 = await inputer.Execute(_currMethod.Steps[1].Options);
                if (inputer.isCancelled || arc_result1 == null)
                    goto cancel;
                else if (arc_result1.ValueX == null)
                    goto step1;
                else
                {
                    _p1 = (Vector2)arc_result1.ValueX;
                    goto step2;
                }
            step2:
                var arc_result2 = await inputer.Execute(_currMethod.Steps[2].Options);
                if (inputer.isCancelled || arc_result2 == null)
                    goto cancel;
                else if (arc_result2.ValueX == null)
                    goto step2;
                else
                {
                    _p2 = (Vector2)arc_result2.ValueX;
                    goto step3;
                }
            step3:
                var arc_result3 = await inputer.Execute(_currMethod.Steps[3].Options);
                if (inputer.isCancelled || arc_result3 == null)
                    goto cancel;
                else  if (arc_result3.ValueX == null)
                    goto step3;
                else
                {
                    _p3 = (Vector2)arc_result3.ValueX;
                    goto step4;
                }
            step4:
                var arc_result4 = await inputer.Execute(_currMethod.Steps[4].Options);
                if (inputer.isCancelled || arc_result4 == null)
                    goto cancel;
                else if (arc_result4.ValueX == null)
                    goto step4;
                else
                {
                    _p4 = (Vector2)arc_result4.ValueX;
                    Create();
                }
            cancel:
                CancelCreate();
            }

            void CancelCreate()
            {
                this.Cancel();
                this.EndCreating();
                this.Clear();
            }
            void Create()
            {
                this.CreateEllipse();
                this.EndCreating();
                this.Clear();
            }
        }
        private void Clear()
        {
            this._p0 = null;
            this._p1 = null;
            this._p2 = null;
            this._p3 = null;
            this._p4 = null;    
        }
        /// <summary>
        /// 椭圆的最终创建
        /// </summary>
        private void CreateEllipse()
        {
            if (_currMethod.Name == "C")
            {
                var p0p1 = (_p1 - _p0);  //从p0指向p1的意思
                var axisX = p0p1.Clone().Normalize();
                docRt.Document.ModelSpace.AddEllipse(this._p0.Clone(), axisX.Angle(), p0p1.Length(), Vector2.Distance(_p2, _p0));

                //var selects1 = this.docRt.Document.ModelSpace.Elements[0];
                //var selects2 = this.docRt.Document.ModelSpace.Elements[1];
                //List<Vector2> points = GeoUtils.GetIntersectionPoints((selects1 as LcEllipse).Ellipse, (selects2 as LcEllipse).Ellipse);

            }
            else if (_currMethod.Name == "")
            {
                var p0p1 = (_p1 - _p0);
                var center = (_p1 + _p0) / 2;
                var radiusX = p0p1.Length() / 2;
                var radiusY = (_p2 - center).Length();
                var axisX = p0p1.Clone().Normalize();
                docRt.Document.ModelSpace.AddEllipse(center.Clone(), axisX.Angle(), radiusX, radiusY);
            }
            else if (_currMethod.Name == "A")
            {
                var p0p1 = (_p1 - _p0);
                var center = (_p1 + _p0) / 2;
                var radiusX = p0p1.Length() / 2;
                var radiusY = (_p2 - center).Length();
                var axisX = p0p1.Clone().Normalize();//需要放在Length后面
                var rotation = axisX.Angle();
                var startAngle = (_p3 - center).Angle() - rotation;
                var endAngle = (_p4 - center).Angle() - rotation;
                if (endAngle < startAngle)
                    endAngle += Utils.TwoPI;
                docRt.Document.ModelSpace.AddEllipse(center.Clone(), rotation, radiusX, radiusY, startAngle, endAngle);
                Ellipse2d ellipse2D = new Ellipse2d();
                ellipse2D.Center = center;
                ellipse2D.Rotation = rotation;
                ellipse2D.RadiusX = radiusX;
                ellipse2D.RadiusY = radiusY;
                ellipse2D.StartAngle = startAngle;
                ellipse2D.EndAngle = endAngle;
                ellipse2D.test();
            }
        }
        public override void Cancel()
        {
            base.Cancel();
            this.vportRt.SetCreateDrawer(null);
        }

        public override void DrawAuxLines(SKCanvas canvas)
        {
            var mp = this.vportRt.PointerMovedPosition.ToVector2d();
            var wcs_mp = this.vportRt.ConvertScrToWcs(mp);
            if (_p0 == null) return;
            var movePoint = mp.ToSKPoint();
            if (_currMethod.Name == "C")
            {
                var center = this.vportRt.ConvertWcsToScr(_p0).ToSKPoint();
                //第二点
                if (_p1 == null)
                {
                    if (center == movePoint) return;
                    canvas.DrawLine(center, movePoint, Constants.auxOrangeDashPen);
                }
                //第三点
                else
                {
                    var p1 = this.vportRt.ConvertWcsToScr(_p1).ToSKPoint();
                    if (p1 == movePoint) return;
                    canvas.DrawLine(center, movePoint, Constants.auxOrangeDashPen);

                    var cV2 = center.ToVector2d();
                    var p1V2 = p1.ToVector2d();
                    var cp1V2 = (p1V2 - cV2);
                    var mvV2 = movePoint.ToVector2d();
                    var cmV2 = (mvV2 - cV2);
                    var mAngle = cmV2.Angle() - cp1V2.Angle();
                    var mY = GeoUtils.PointDistanceToLine(mvV2, cV2, p1V2);
                    var radiusY = mY / Math.Sin(mAngle);
                    getEllipse(cV2, cp1V2.Clone().Normalize(), cp1V2.Length(), radiusY, out var rect, out var angle);
                    canvas.RotateRadians((float)angle, center.X, center.Y);
                    canvas.DrawOval(rect, new SKPaint { Color = this.vportRt.GetAuxColorValue(), IsStroke = true });
                    canvas.RotateRadians(-(float)angle, center.X, center.Y);

                }
            }
            else if (_currMethod.Name == "")
            {
                var axis0 = this.vportRt.ConvertWcsToScr(_p0);
                var axis0Sk = axis0.ToSKPoint();
                //轴线另一个端点
                if (_p1 == null)
                {
                    if (axis0Sk == movePoint) return;
                    canvas.DrawLine(axis0Sk, movePoint, Constants.auxOrangeDashPen);
                }
                else //另一个轴的长度
                {
                    var axis1 = this.vportRt.ConvertWcsToScr(_p1);
                    var centerScr = this.vportRt.ConvertWcsToScr((_p1 + _p0) / 2).ToSKPoint();
                    canvas.DrawLine(centerScr, movePoint, Constants.auxOrangeDashPen);

                    var axisX = (axis1 - axis0).Normalize();
                    getEllipse(centerScr.ToVector2d(), axisX, (axis0 - axis1).Length() / 2, (movePoint - centerScr).Length, out var rect, out var angle);
                    canvas.RotateRadians((float)angle, centerScr.X, centerScr.Y);
                    canvas.DrawOval(rect, new SKPaint { Color = this.vportRt.GetAuxColorValue(), IsStroke = true });
                    canvas.RotateRadians(-(float)angle, centerScr.X, centerScr.Y);

                }
            }
            else if (_currMethod.Name == "A")
            {
                var axis0 = this.vportRt.ConvertWcsToScr(_p0);
                //轴线另一个端点
                if (_p1 == null)
                {
                    var axis0P = axis0.ToSKPoint();
                    if (axis0P == movePoint) return;
                    canvas.DrawLine(axis0P, movePoint, Constants.auxOrangeDashPen);
                }
                else //另一个轴的长度
                {
                    var axis1 = this.vportRt.ConvertWcsToScr(_p1);
                    var center = (_p1 + _p0) / 2;
                    var centerScr = this.vportRt.ConvertWcsToScr(center);
                    var axisX = (axis1 - axis0).Normalize();
                    var radiusX = (axis1 - axis0).Length() / 2;
                    double radiusY = 0;
                    canvas.DrawLine(centerScr.ToSKPoint(), movePoint, Constants.auxOrangeDashPen);
                    if (_p2 == null)
                        radiusY = (mp - centerScr).Length();
                    else
                        radiusY = (this.vportRt.ConvertWcsToScr(_p2) - centerScr).Length();
                    getEllipse(centerScr, axisX, radiusX, radiusY, out var rect, out var angle);
                    canvas.RotateRadians((float)angle, (float)centerScr.X, (float)centerScr.Y);
                    if (_p3 == null)
                        canvas.DrawOval(rect, new SKPaint { Color = this.vportRt.GetAuxColorValue(), IsStroke = true } );
                    else
                    {
                        var scrP3 = this.vportRt.ConvertWcsToScr(_p3);
                        var startAngle =-((scrP3 - centerScr).Angle()- axisX.Angle());
                        var endAngle = -((mp - centerScr).Angle()-axisX.Angle());
                        if (endAngle < startAngle)
                            endAngle += Utils.TwoPI;
                        var sweepAngle = (endAngle - startAngle);
                        using (var skPath = new SKPath())
                        {
                            rect = new SKRect(rect.Left, rect.Bottom, rect.Right, rect.Top);
                            var  startDegree = Utils.RadianToDegree(startAngle);
                            var sweepDegree = Utils.RadianToDegree(sweepAngle);
                            skPath.ArcTo(rect, -(float)startDegree, -(float)sweepDegree, true);
                            canvas.DrawPath(skPath, new SKPaint { Color = this.vportRt.GetAuxColorValue(), IsStroke = true });
                        }
                    }
                    canvas.RotateRadians(-(float)angle, (float)centerScr.X, (float)centerScr.Y) ;

                }
            }
        }
        //public override void Draw(SKCanvas canvas, LcElement element, Matrix3 matrix)
        //{
        //    var ellipse = element as LcEllipse;
        //    var mcenter = matrix.MultiplyPoint(ellipse.Center);
        //    var axisY = Vector2.RotateInRadian(ellipse.AxisX, Utils.HalfPI);
        //    var mT = matrix.MultiplyPoint(ellipse.Center + axisY * ellipse.RadiusY);
        //    var mR = matrix.MultiplyPoint(ellipse.Center + ellipse.AxisX * ellipse.RadiusX);

        //    var scCenter = this.vportRt.ConvertWcsToScr(mcenter);
        //    var scMT = this.vportRt.ConvertWcsToScr(mT);
        //    var scMR = this.vportRt.ConvertWcsToScr(mR);
        //    var angle = (float)(scMR - scCenter).Angle();
        //    var hwidth = Vector2.Distance(scCenter, scMR);
        //    var hheight = Vector2.Distance(scCenter, scMT);
        //    var rect = new SKRect((float)(scCenter.X - hwidth), (float)(scCenter.Y + hheight), (float)(scCenter.X + hwidth), (float)(scCenter.Y - hheight));
        //    //get Layer color 
        //    bool isDragCopy = (matrix != Matrix3.Zero);
        //    var pen = this.GetDrawPen(ellipse, isDragCopy);
        //    var skScCenter = scCenter.ToSKPoint();
        //    canvas.RotateRadians(angle, skScCenter.X, skScCenter.Y);
        //    var sweepAngle = -(float)Utils.RadianToDegree(ellipse.EndAngle - ellipse.StartAngle);
        //    if (Math.Abs(sweepAngle) >= 360)
        //        canvas.DrawOval(rect, pen);
        //    else
        //        using (var skPath = new SKPath())
        //        {
        //            rect = new SKRect(rect.Left, rect.Bottom, rect.Right, rect.Top);
        //            var startAngle = -(float)Utils.RadianToDegree(ellipse.StartAngle);
        //            skPath.ArcTo(rect, startAngle, sweepAngle, true);
        //            canvas.DrawPath(skPath, pen);
        //        }
        //    canvas.RotateRadians(-angle, skScCenter.X, skScCenter.Y);
        //}
        private void getEllipse(Vector2 center, Vector2 axisX, double radiusX, double radiusY, out SKRect rect, out double angle)
        {
            angle = axisX.Angle();
            rect = new SKRect((float)(center.X - radiusX), (float)(center.Y + radiusY), (float)(center.X + radiusX), (float)(center.Y - radiusY));
        }

        /// <summary>
        /// 拖拽点的设置
        /// </summary>
        /// <param name="element"></param>
        /// <returns></returns>
        public override ControlGrip[] GetControlGrips(LcElement element)
        {
            this._ellipse = element as LcEllipse;
            var ellipse = _ellipse;
            var mcenter = (ellipse.Center);
            var axisY = Vector2.RotateInRadian(ellipse.AxisX, Utils.HalfPI);
            var mT = (ellipse.Center + axisY * ellipse.RadiusY);
            var mB = (ellipse.Center - axisY * ellipse.RadiusY);
            var mR = (ellipse.Center + ellipse.AxisX * ellipse.RadiusX);
            var mL = (ellipse.Center - ellipse.AxisX * ellipse.RadiusX);
            return new ControlGrip[] 
            {
                new ControlGrip{Name="Center",Position=mcenter,Element=element },
                new ControlGrip{ Name="Top",Position=mT,Element=element},
                new ControlGrip{ Name="Bottom",Position=mB,Element=element},
                new ControlGrip{ Name="Left",Position=mL,Element=element},
                new ControlGrip{ Name="Right",Position=mR,Element=element},
            };
        }
 
        public override void DrawDragGrip(SKCanvas canvas)
        {
            Vector2 scCenter, scMT, scMR;
            double angle, hwidth, hheight ;
            Vector2 center = _center;
            Vector2 radiusXY = _radiusXY;
            if (center == null)
                return;
            switch (_gripName)
            {
                case "Center":
                    center = _position;
                    break;
                case "Top":
                case "Bottom":
                    radiusXY.Y = (_position - center).Length();
                    break;
                case "Left":
                case "Right":
                    radiusXY.X = (_position - center).Length();
                    break;
                default:
                    break;
            }
            scCenter = this.vportRt.ConvertWcsToScr(center);
            scMT = this.vportRt.ConvertWcsToScr(center + radiusXY.Y * _axisY);
            scMR = this.vportRt.ConvertWcsToScr(center + radiusXY.X * _axisX);
            angle = (float)(scMR - scCenter).Angle();
            hwidth = Vector2.Distance(scCenter, scMR);
            hheight = Vector2.Distance(scCenter, scMT);
            var rect = new SKRect((float)(scCenter.X - hwidth), (float)(scCenter.Y + hheight), (float)(scCenter.X + hwidth), (float)(scCenter.Y - hheight));
            canvas.RotateRadians((float)angle, (float)scCenter.X,(float) scCenter.Y);
            canvas.DrawOval(rect,Constants.auxElementPen);
            canvas.RotateRadians((float)-angle, (float)scCenter.X,(float) scCenter.Y);

        }

        /// <summary>
        /// 拖拽完成后渲染
        /// </summary>
        private LcEllipse _ellipse;
        private string _gripName;
        private Vector2 _position;
        private Vector2 _center;
        private Vector2 _radiusXY;
        private Vector2 _axisX;
        private Vector2 _axisY;
        public override void SetDragGrip(LcElement element, string gripName, Vector2 position, bool isEnd)
        {
            var ellipse = element as LcEllipse;
            _ellipse = ellipse;
            if (!isEnd)
            {
                _gripName = gripName;
                _position = position;
                _center = (ellipse.Center);
                _radiusXY = new Vector2(ellipse.RadiusX, ellipse.RadiusY);
                _axisX = ellipse.AxisX;
                _axisY = Vector2.RotateInRadian(_axisX, Utils.HalfPI);
            }
            else
            {
                switch (gripName)
                {
                    case "Center":
                        //_ellipse.Center = position;
                        _ellipse.Set(center: position);
                        break;
                    case "Top":
                        //var axisY = Vector2.RotateInRadian(ellipse.AxisX, Utils.HalfPI);
                        //var r1 = _ellipse.Center + axisY * ellipse.RadiusY;
                        var r1 = Vector2.Distance(_ellipse.Center, position);
                        _ellipse.Set(radiusY: r1);
                        break;
                    case "Bottom":
                        var r2 = Vector2.Distance(_ellipse.Center, position);
                        _ellipse.Set(radiusY: r2);
                        // _ellipse.RadiusY = (_position - _ellipse.Center).Length();
                        break;
                    case "Left":
                        var x1 = Vector2.Distance(_ellipse.Center, position);
                        _ellipse.Set(radiusX: x1);
                        break;
                    case "Right":
                        var x2 = Vector2.Distance(_ellipse.Center, position);
                        _ellipse.Set(radiusX: x2);
                        //_ellipse.RadiusX = (_position - _ellipse.Center).Length();
                        break;
                    default:
                        return;
                }
            }
        }

        public override List<PropertyObserver> GetPropertyObservers()
        {
            return new List<PropertyObserver>()
            {
                 new PropertyObserver()
                {
                    Name = "StartpX",
                    DisplayName = "起点 X 坐标",
                    Getter = (ele) => Math.Round((ele as LcEllipse).AxisX.X, 4),
                     //Setter = (ele, value) =>
                     //{
                     //   var LcEllipse = (ele as LcEllipse);
                     //   var y = Convert.ToDouble(value);
                     //   var start = new Vector2( LcEllipse.Center.X, y);
                     //   LcEllipse.Set(center : start);

                     //}
                },
                 new PropertyObserver()
                {
                    Name = "StartpY",
                    DisplayName = "起点 Y 坐标",
                    Getter = (ele) => Math.Round((ele as LcEllipse).AxisX.Y, 4)
                },
                 new PropertyObserver()
                {
                    Name = "StartpZ",
                    DisplayName = "起点 Z 坐标",
                    Getter = (ele) => 0
                },
                  new PropertyObserver()
                {
                    Name = "CenterX",
                    DisplayName = "圆心 X 坐标",
                    Getter = (ele) => Math.Round((ele as LcEllipse).Center.X, 4),
                    Setter = (ele, value) =>
                    {
                        var lcEllipse = (ele as LcEllipse);
                        var x = Convert.ToDouble(value);
                        var cen = new Vector2(x, lcEllipse.Center.Y);
                        lcEllipse.Set(center : cen);
                        //(ele as LcEllipse).Center= cen;
                    }
                },
                  new PropertyObserver()
                {
                    Name = "CenterY",
                    DisplayName = "圆心 Y 坐标",
                    Getter = (ele) => Math.Round((ele as LcEllipse).Center.Y, 4),
                    Setter = (ele, value) =>
                    {
                         var lcEllipse = (ele as LcEllipse);
                         var y = Convert.ToDouble(value);
                         var cen = new Vector2(lcEllipse.Center.X, y);
                        lcEllipse.Set(center : cen);
                         //(ele as LcEllipse).Center= cen;
                    }
                },
                    new PropertyObserver()
                {
                    Name = "CenterZ",
                    DisplayName = "圆心 Z 坐标",
                    Getter = (ele) => 0
                },
                     new PropertyObserver()
                {
                    Name = "EndpX",
                    DisplayName = "端点 X 坐标",
                    Getter = (ele) => Math.Round((ele as LcEllipse).AxisX.X, 4)
                },
                    new PropertyObserver()
                {
                    Name = "EndpY",
                    DisplayName = "端点 Y 坐标",
                    Getter = (ele) => Math.Round((ele as LcEllipse).AxisX.Y, 4)
                },
                    new PropertyObserver()
                {
                    Name = "EndpZ",
                    DisplayName = "端点 Z 坐标",
                    Getter = (ele) => 0
                 },
                    new PropertyObserver()
                {
                    Name = "MaxRidus",
                    DisplayName = "长轴半径",    //X轴半径
                    Getter = (ele) =>
                    {
                        if((ele as LcEllipse).RadiusX>(ele as LcEllipse).RadiusY)
                        {
                            return (ele as LcEllipse).RadiusX;
                        }
                        else
                        {
                            return (ele as LcEllipse).RadiusY;
                        }
                    },
                    Setter = (ele, value) =>
                    {
                        var  maxRidus= Convert.ToDouble(value);
                        if((ele as LcEllipse).RadiusX>(ele as LcEllipse).RadiusY)
                        {
                            (ele as LcEllipse).Set(radiusX:maxRidus);
                            //(ele as LcEllipse).RadiusX= maxRidus;
                        }
                        else
                        {
                            (ele as LcEllipse).Set(radiusY:maxRidus);
                             //(ele as LcEllipse).RadiusY= maxRidus;
                        }
                    }
                },
                    new PropertyObserver()
                {
                    Name = "RidusY",
                    DisplayName = "短轴半径",   //Y轴半径
                    Getter = (ele) =>
                    {
                        if((ele as LcEllipse).RadiusX<(ele as LcEllipse).RadiusY)
                        {
                            return (ele as LcEllipse).RadiusX;
                        }
                        else
                        {
                            return (ele as LcEllipse).RadiusY;
                        }
                    },
                    Setter = (ele, value) =>
                    {
                        var  minRidus= Convert.ToDouble(value);
                        if((ele as LcEllipse).RadiusX<(ele as LcEllipse).RadiusY)
                        {
                            (ele as LcEllipse).Set(radiusX:minRidus);
                            //(ele as LcEllipse).RadiusX= minRidus;
                        }
                        else
                        {
                            (ele as LcEllipse).Set(radiusY:minRidus);
                             //(ele as LcEllipse).RadiusY= minRidus;
                        }
                    }
                },
                     new PropertyObserver()
                {
                    Name = "RadiusProportion",
                    DisplayName = "半径比例",
                    Getter = (ele) =>
                    {
                        return (ele as LcEllipse).RadiusX/(ele as LcEllipse).RadiusY;

                    },
                    Setter = (ele, value) =>
                    {
                         var  radiusProportion= Convert.ToDouble(value);
                        (ele as LcEllipse).Set(radiusX:(radiusProportion*(ele as LcEllipse).RadiusY));
                         //(ele as LcEllipse).RadiusX= radiusProportion*(ele as LcEllipse).RadiusY;
                    }
                },
                           new PropertyObserver()
                {
                    Name = "MaxX",
                    DisplayName = "长轴矢量 X 坐标",
                    Getter = (ele) =>
                    {
                        LcEllipse lcEllipse =ele as LcEllipse;
                        double StartAngle = (Math.Atan2(lcEllipse.AxisX.Y - lcEllipse.Center.Y, lcEllipse.AxisX.X - lcEllipse.Center.X) * 180 / Math.PI);
                        if (lcEllipse.RadiusY > lcEllipse.RadiusX)
                        {
                           double MaxX=Math.Sin(StartAngle*Math.PI/180)*lcEllipse.RadiusY;
                            return MaxX;
                        }
                        else
                        {
                            double MaxX=Math.Sin(StartAngle*Math.PI/180)*lcEllipse.RadiusX;
                           return MaxX;
                        }
                    },
                },
                        new PropertyObserver()
                {
                    Name = "MaxY",
                    DisplayName = "长轴矢量 Y 坐标",
                    Getter = (ele) =>
                    {
                        LcEllipse lcEllipse =ele as LcEllipse;
                        double StartAngle = (Math.Atan2(lcEllipse.AxisX.Y - lcEllipse.Center.Y, lcEllipse.AxisX.X - lcEllipse.Center.X) * 180 / Math.PI);
                        if (lcEllipse.RadiusY > lcEllipse.RadiusX)
                        {
                          double MaxY=Math.Cos(StartAngle*Math.PI/180)*lcEllipse.RadiusY;
                            return MaxY;
                        }
                        else
                        {
                            double MaxY=Math.Cos(StartAngle*Math.PI/180)*lcEllipse.RadiusX;
                            return MaxY;
                        }
                    },
                },
                        new PropertyObserver()
                {
                    Name = "MaxZ",
                    DisplayName = "长轴矢量 Z 坐标",
                    Getter = (ele) =>0,
                },
                      new PropertyObserver()
                {
                    Name = "MinX",
                    DisplayName = "短轴矢量 X 坐标",
                    Getter = (ele) =>
                    {
                        LcEllipse lcEllipse =ele as LcEllipse;
                        double StartAngle = (Math.Atan2(lcEllipse.AxisX.Y - lcEllipse.Center.Y, lcEllipse.AxisX.X - lcEllipse.Center.X) * 180 / Math.PI);
                        if (lcEllipse.RadiusY < lcEllipse.RadiusX)
                        {
                           double MinX=Math.Sin(StartAngle*Math.PI/180)*lcEllipse.RadiusY;
                            return MinX;
                        }
                        else
                        {
                            double MinX=Math.Sin(StartAngle*Math.PI/180)*lcEllipse.RadiusX;
                           return MinX;
                        }
                    },
                },
                        new PropertyObserver()
                {
                    Name = "MinY",
                    DisplayName = "短轴矢量 Y 坐标",
                    Getter = (ele) =>
                    {
                        LcEllipse lcEllipse =ele as LcEllipse;
                        double StartAngle = (Math.Atan2(lcEllipse.AxisX.Y - lcEllipse.Center.Y, lcEllipse.AxisX.X - lcEllipse.Center.X) * 180 / Math.PI);
                        if (lcEllipse.RadiusY < lcEllipse.RadiusX)
                        {
                           double MinX=Math.Sin(StartAngle*Math.PI/180)*lcEllipse.RadiusY;
                            return MinX;
                        }
                        else
                        {
                            double MinX=Math.Sin(StartAngle*Math.PI/180)*lcEllipse.RadiusX;
                           return MinX;
                        }
                    },
                },
                        new PropertyObserver()
                {
                    Name = "MinZ",
                    DisplayName = "短轴矢量 Z 坐标",
                    Getter = (ele) =>0,
                },
                         new PropertyObserver()
                {
                    Name = "Area",
                    DisplayName = "面积",
                    Getter = (ele) =>
                    {
                        double S=Math.Round((Math.PI*(ele as LcEllipse).RadiusX*(ele as LcEllipse).RadiusY),4);
                        return S;
                    },
                },
            };
        }
    }
}
